import { ExclamationCircleOutlined, QuestionCircleOutlined } from '@ant-design/icons';
import { Button, Popconfirm, Select, Tooltip } from "antd";
import { MouseEvent, useState } from "react";

const BatchOperation = <T,>(props: BatchOperationProps<T>) => {

  const {
    size = 'small',
    buttonText = '批量操作',
    options = [],
    manualPop = true,
    tips: globalTips,
    disable: globalDisable,
    onOk: globalOk,
    onCancel: globalCancel,
    onChange
  } = props;

  const [confirmOpen, setConfirmOpen] = useState<boolean>(false);
  // const [loading, setLoading] = useState<boolean>(false);
  const [selectedValue, setSelectedValue] = useState<T>(options[0]?.value);
  const [manualDisable, setManualDisable] = useState<boolean>(false);

  const {
    confirm = true,
    confirmText,
    confirmIcon = <ExclamationCircleOutlined />,
    tips = globalTips,
    disable = globalDisable,
    onOk = globalOk,
    onCancel = globalCancel
  } = options.find(({ value }) => value === selectedValue) || {};

  return <div style={{ padding: 4, border: '1px solid #d8d8d8', display: 'inline-flex', gap: 6 }}>
    <div>
      <Select<any>
        options={options.map(({ value, label }) => ({ value, label } as any))} defaultValue={selectedValue}
        dropdownMatchSelectWidth={false} showSearch={false}
        size={size} style={{ width: 'max-content', maxWidth: 160 }}
        onChange={selValue => {
          setSelectedValue(selValue);
          const selected = options.find(({ value }) => value === selValue);
          if (!!selected) {
            onChange?.(selected, () => setManualDisable(true));
          } else {
            throw '选项错误';
          }
        }}></Select>
    </div>
    {
      (!!confirmText || confirm)
        ? (
          <Popconfirm
            placement="topRight" title={confirmText || '确认要批量操作？'} visible={manualPop ? confirmOpen : undefined} icon={confirmIcon}
            onCancel={() => {
              try {
                const selected = options.find(({ value }) => value === selectedValue);
                if (selected)
                  onCancel?.(selected);
              } finally {
                if (manualPop) setConfirmOpen(false);
              }
            }}
            onConfirm={async () => {
              // setLoading(true);
              try {
                const selected = options.find(({ value }) => value === selectedValue);
                if (selected)
                  await onOk?.(selected);
              } finally {
                if (manualPop) setConfirmOpen(false);
                // setLoading(false);
              }
            }}
          >
            <Button type="primary" size={size} /* loading={loading} */ disabled={manualDisable || disable} onClick={() => {
              if (manualPop) setConfirmOpen(true);
            }}>
              {buttonText}
              {
                !!tips &&
                <Tooltip title={
                  <div style={{ display: 'inline-flex', alignItems: 'center' }}>
                    <ExclamationCircleOutlined />
                    <div style={{ marginLeft: 6, fontSize: 12 }}>{tips}</div>
                  </div>
                }>
                  <QuestionCircleOutlined style={{ marginLeft: 5 }} />
                </Tooltip>
              }
            </Button>
          </Popconfirm>
        )
        : (
          <Button type="primary" size={size} /* loading={loading} */ disabled={manualDisable || disable} onClick={async event => {
            // setLoading(true);
            try {
              const selected = options.find(({ value }) => value === selectedValue);
              if (selected)
                await onOk?.(selected, event);
            } finally {
              // setLoading(false);
            }
          }}>
            {buttonText}
            {
              !!tips &&
              <Tooltip title={
                <div style={{ display: 'inline-flex', alignItems: 'center' }}>
                  <ExclamationCircleOutlined />
                  <div style={{ marginLeft: 6, fontSize: 12 }}>{tips}</div>
                </div>
              }>
                <QuestionCircleOutlined style={{ marginLeft: 5 }} />
              </Tooltip>
            }
          </Button>
        )
    }
  </div>;
};

export default BatchOperation;

export interface OperationType<T> {
  /**
   * 操作选项的值
   */
  value: T;
  /**
   * 操作选项的显示文本
   */
  label: string;
  /**
   * 温馨提示的文本
   */
  tips?: string;
  /**
   * 点击后是否需要再次确认
   */
  confirm?: boolean;
  /**
   * 点击后再次确认的提示文本，设置该项confirm固定为true
   */
  confirmText?: string | React.ReactNode;
  /**
     * 点击后再次确认的提示文本，设置该项confirm固定为true
     */
  confirmIcon?: false | React.ReactNode;
  /**
   * 禁用，没有会用全局的
   * @returns
   */
  disable?: boolean
  /**
   * 最终确认后该选项独立的执行函数，没有会用全局的
   * @returns
   */
  onOk?: (selectedOption: Readonly<Omit<OperationType<T>, 'onOk' | 'onCancel'>>, event?: MouseEvent) => Promise<void>;
  /**
   * 有confirm时，取消时执行的函数，没有会用全局的
   * @returns
   */
  onCancel?: (selectedOption: Readonly<Omit<OperationType<T>, 'onOk' | 'onCancel'>>) => void;
}

interface BatchOperationProps<T> {
  size?: 'small' | 'middle' | 'large'
  /**
   * 按钮文本
   */
  buttonText?: string
  /**
   * 可以进行的操作选项
   */
  options: OperationType<T>[]
  /**
   * 温馨提示，可被选项覆盖
   */
  tips?: string
  /**
   * 手动控制confirm弹窗关闭
   */
  manualPop?: boolean
  /**
   * 所有选项的禁用，可被选项覆盖
   * @returns
   */
  disable?: boolean
  /**
   * 所有选项最终确认后执行的函数，可被选项覆盖
   * @returns
   */
  onOk?: (selectedOption: Readonly<Omit<OperationType<T>, 'onOk' | 'onCancel'>>, event?: MouseEvent) => Promise<void>
  /**
   * 有confirm时，所有选项取消时执行的函数，可被选项覆盖
   * @returns
   */
  onCancel?: (selectedOption: Readonly<Omit<OperationType<T>, 'onOk' | 'onCancel'>>) => void
  /**
   * 选项变更
   * @returns
   */
  onChange?: (selectedOption: Readonly<Omit<OperationType<T>, 'onOk' | 'onCancel'>>, setDisabled: () => void) => void
}
